const EVENT_REGEXP = /on(\w+)/

interface JsxEvents {
  el: HTMLElement
  name: string
  listener: Function
}

let events = [] as JsxEvents[]

export function collectJsxEvents(createJsx: () => HTMLElement) {
  events.splice(0)
  const htmlElement = createJsx()
  return {
    htmlElement,
    events: events.concat(),
  }
}

export function disposeJsxEvents(events: JsxEvents[]) {
  events.forEach(i => {
    i.el.removeEventListener(i.name, i.listener as any)
  })
}

const asAttributeNames = ['className']

export function h(tagName: string, props: { [key: string]: any }, ...children: any[]) {
  const el = document.createElement(tagName)
  for (let propName in props) {
    if (props.hasOwnProperty(propName)) {
      const propValue = props[propName]
      if (propName === 'ref') {
        propValue(el)
        continue
      } else {
        const matchResult = propName.match(EVENT_REGEXP)
        //console.log(propName, propValue, typeof propValue)
        if (matchResult) {
          let eventName = matchResult[1]
          if (eventName.charCodeAt(0) < 97) {
            eventName = eventName.toLowerCase()
            el.addEventListener(eventName, propValue)
            events.push({
              el,
              name: eventName,
              listener: propValue,
            })
            continue
          }
        }
      }
      const asProp = asAttributeNames.includes(propName) || propName.startsWith('data-')
      if (asProp) {
        // @ts-ignore
        el[propName] = props[propName]
      } else {
        el.setAttribute(propName, props[propName])
      }
    }
  }

  children.forEach(child => {
    if (typeof child === 'string') {
      el.appendChild(document.createTextNode(child))
    } else if (child instanceof HTMLElement) {
      el.appendChild(child)
    } else {
      console.error('Invalid child:', child)
    }
  })

  return el
}